﻿using System;
using System.Runtime.InteropServices;

namespace ClewareWrapper.Invoke
{
    /// <summary>
    /// Low level Wrapper for USBAccess.dll (4.0.0) to access to USB HID devices from Cleware GmbH.
    /// </summary>
    /// <remarks>
    /// Before using the functionals interface, the access must be prepared by calling the function
    /// InitObject(). The returned value is used as the first argument in all other 
    /// functions. Before leaving the program, the function UnInitObject(obj) will do the
    /// cleanup of the the environment.
    /// </remarks>
    public static class UsbAccessWrapper
    {
        /// <summary>
        /// Initialize the functional interface.
        /// Return Type: CUSBaccess*
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWInitObject")]
        public static extern System.IntPtr InitObject();

        /// <summary>
        /// Closes the functional interface.
        /// Return Type: void
        /// obj: CUSBaccess*
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWUnInitObject")]
        public static extern void UnInitObject(System.IntPtr obj);

        /// <summary>
        /// Looks for Cleware USB devices and opens them. The number of found devices is
        /// returned.
        /// Return Type: int
        /// obj: CUSBaccess*
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWOpenCleware")]
        public static extern int OpenCleware(System.IntPtr obj);

        /// <summary>
        /// Closes all open Cleware USB devices.
        /// Return Type: int
        /// obj: CUSBaccess*
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWCloseCleware")]
        public static extern int CloseCleware(System.IntPtr obj);

        /// <summary>
        /// When reading from and writing to the USB device failed several times, the device could
        /// be automatically searched and setup to the initial state.
        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWRecover")]
        public static extern int Recover(System.IntPtr obj, int deviceNo);

        /// <summary>
        /// For later use.
        /// Return Type: HANDLE->void*
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWGetHandle")]
        public static extern System.IntPtr GetHandle(System.IntPtr obj, int deviceNo);

        /// <summary>
        /// For later use. The return value is 0 in case of an error, else > 0.
        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// buf: unsigned char*
        /// bufsize: int
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWGetValue")]
        public static extern int GetValue(System.IntPtr obj, int deviceNo, System.IntPtr buf, int bufsize);

        /// <summary>
        /// For later use. The return value is 0 in case of an error, else > 0..
        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// buf: unsigned char*
        /// bufsize: int
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWSetValue")]
        public static extern int SetValue(System.IntPtr obj, int deviceNo, System.IntPtr buf, int bufsize);

        /// <summary>
        /// For later use. The return value is 0 in case of an error, else > 0.
        /// value: 0=off 7=medium 15=highlight
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWSetLED")]
        public static extern int SetLED(System.IntPtr obj, int deviceNo, LedId Led, int value);

        /// <summary>
        /// Turns an USB-Switch on or off. The argument “Switch” defines which switch to set. If
        /// the argument “On” is 1, the switch is turned on. If “On” is 0, the switch is turned off. The
        /// return value is 0 in case of an error, else > 0.
        /// On: 0=off, 1=on
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWSetSwitch")]
        public static extern int SetSwitch(System.IntPtr obj, int deviceNo, SwitchId Switch, int On);

        /// <summary>
        /// Get the current switch state. The argument “Switch” defines which switch to get the status
        /// from. If the returned value is 1 if the switch is on and it is 0 otherwise. In case of an error,
        /// the return value is set to –1.
        /// On: 0=off, 1=on, -1=error
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWGetSwitch")]
        public static extern int GetSwitch(System.IntPtr obj, int deviceNo, SwitchId Switch);

        /// <summary>
        /// Get the current switch state. The argument “Switch” defines which switch to get the status
        /// from. If the returned value is 1 if the switch is on and it is 0 otherwise. The seqNum
        /// argument should be 0. In case of an error, the return value is set to –1.
        /// This command solves the problem that the USB data is buffered and maybe outdated.
        /// Using GetSeqSwitch will repeatedly get data from the buffer until the state represent the
        /// situation at the time of the call.*
        /// On: 0=off, 1=on, -1=error
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWGetSeqSwitch")]
        public static extern int GetSeqSwitch(System.IntPtr obj, int deviceNo, SwitchId Switch, int seqNum);

        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// switchCount: int*
        /// buttonAvailable: int*
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWGetSwitchConfig")]
        public static extern int GetSwitchConfig(System.IntPtr obj, int deviceNo, ref int switchCount, ref int buttonAvailable);

        /// <summary>
        /// Calibration of a temperature device. The second parameter “Sollwert” is the correct
        /// temperature and the “Istwert” is the current value to be corrected. The return value is 0 in
        /// case of an error, else > 0.
        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// Sollwert: double
        /// Istwert: double
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWSetTempOffset")]
        public static extern int SetTempOffset(System.IntPtr obj, int deviceNo, double Sollwert, double Istwert);

        /// <summary>
        /// Request for the current temperature. This function will set the temperature and timeID to
        /// the actual values. The returned time is based on a device internal time. This time is used
        /// to assure that two requests deliver different times. At least one second must separate
        /// adjacent calls. If several requests returns the same time, the device may be in trouble and
        /// a reset is necessary. This must be initiated by calling the “ResetDevice” function. The
        /// return value is 0 in case of an error, else > 0.
        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// Temperature: double*
        /// timeID: int*
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWGetTemperature")]
        public static extern int GetTemperature(System.IntPtr obj, int deviceNo, ref double Temperature, ref int timeID);

        /// <summary>
        /// Request for the current humidity. This function will set the humidity and timeID to the
        /// actual values. The returned time is based on a device internal time. This time is used to
        /// assure that two requests deliver different times. At least two seconds must separate
        /// adjacent calls. The return value is 0 in case of an error, else > 0.
        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// Humidity: double*
        /// timeID: int*
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWGetHumidity")]
        public static extern int GetHumidity(System.IntPtr obj, int deviceNo, ref double Humidity, ref int timeID);

        /// <summary>
        /// Reset a Cleware device. The return value is 0 in case of an error, else > 0. If the device is
        /// a temperature or humidity sensor, the command causes a hardware reset of the sensor.
        /// Other devices will do a cold start when disconnected for a short time.
        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWResetDevice")]
        public static extern int ResetDevice(System.IntPtr obj, int deviceNo);

        /// <summary>
        /// The USB-Humidity must get a start command to enter the measuring loop. This command
        /// must be send after a reset or when the commands SetValue oder GetValue were used.
        /// When StartDevice is called for other devices it will be ignored. In case of an error, the
        /// return value ist 0, otherwise != 0.
        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWStartDevice")]
        public static extern int StartDevice(System.IntPtr obj, int deviceNo);

        /// <summary>
        /// Send a life signal to an USB-Wathdog. The time until the next life signal must be detected
        /// is supplied in minutes. If “time1” is –1 the device is activated immediately (USBAutoReset).
        /// The return value is 0 in case of an error, else > 0.
        /// If the device is an USB-AutoReset “time2” defines the time distance for the secondary
        /// reset for cases the first reset will not restart the PC up to point where life signals will be
        /// send again. The value is defined in minutes and could be in the range 0 – 255. If the value
        /// is 0, the secondary reset is turned off.
        /// If the device is an USB-WatchLight, the green light is turned on when the CalmWatchdog
        /// command is executed. The argument “time1” defines the offset in seconds until the red
        /// light is turned on. The yellow light is turned on after “time2” seconds.
        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// minutes: int
        /// minutes2restart: int
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWCalmWatchdog")]
        public static extern int CalmWatchdog(System.IntPtr obj, int deviceNo, int minutes, int minutes2restart);

        /// <summary>
        /// Version number of this device.
        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWGetVersion")]
        public static extern int GetVersion(System.IntPtr obj, int deviceNo);

        /// <summary>
        /// Device type. Possible values are defined in the USBtype_enum, eg. SWITCH1_DEVICE
        /// or TEMPERATURE2_DEVICE.
        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWGetUSBType")]
        public static extern UsbType GetUSBType(System.IntPtr obj, int deviceNo);

        /// <summary>
        /// Serial number of this device.
        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWGetSerialNumber")]
        public static extern int GetSerialNumber(System.IntPtr obj, int deviceNo);

        /// <summary>
        /// Get the version of the DLL.
        /// Return Type: int
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWGetDLLVersion")]
        public static extern int GetDLLVersion();

        /// <summary>
        /// If the device is configured as an USB-Watchdog or USB-AutoReset, this counter reflects
        /// how often a reset was done by an USB command.
        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWGetManualOnCount")]
        public static extern int GetManualOnCount(System.IntPtr obj, int deviceNo);

        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWGetManualOnTime")]
        public static extern int GetManualOnTime(System.IntPtr obj, int deviceNo);

        /// <summary>
        /// Get the “turned on by USB command” counter (USB-Switch version 15 and higher). In
        /// case of an error –1 will be returned. If the device is configured as an USB-Watchdog or
        /// USB-AutoReset, this counter reflects how often a reset was done by missing the USB life
        /// signal.
        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWGetOnlineOnCount")]
        public static extern int GetOnlineOnCount(System.IntPtr obj, int deviceNo);

        /// <summary>
        /// These commands are used with an USB-Switch equiped with a button for manual
        /// switching. In case of an error –1 will be returned.
        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWGetOnlineOnTime")]
        public static extern int GetOnlineOnTime(System.IntPtr obj, int deviceNo);

        /// <summary>
        /// All input channels of the devices USB-Contact and USB-IO16 could be scanned with the
        /// command “GetMultiSwitch”. The argument “mask” indicates the channels which changes
        /// the values since the last call of GetMultiSwitch. Channel 0 is the least significant bit
        /// (LSB). The argument shows the current status of all channels. The argument “seqNum”
        /// should be set to 0.
        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// param2: unsigned int
        /// mask: int*
        /// param4: unsigned int
        /// value: int*
        /// seqNumber: int
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWGetMultiSwitch")]
        public static extern int GetMultiSwitch(System.IntPtr obj, int deviceNo, uint param2, ref int mask, uint param4, ref int value, int seqNumber);

        /// <summary>
        /// All output channels of the USB-IO16 will be set with the command “SetMultiSwitch”.
        /// The argument “value” holds the new state of the channels. Channel 0 is the least
        /// significant bit (LSB).
        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// param2: unsigned int
        /// value: int
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWSetMultiSwitch")]
        public static extern int SetMultiSwitch(System.IntPtr obj, int deviceNo, uint param2, int value);

        /// <summary>
        /// The configuration of the USB-IO16 is defined with the command SetMultiConfig. Every
        /// channel is assigned a bit in the direction argument. Channel 0 is the least significant bit
        /// (LSB). If the bit is 0 the channel is configured as an input, otherwise as an output.
        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// param2: unsigned int
        /// directions: int
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWSetMultiConfig")]
        public static extern int SetMultiConfig(System.IntPtr obj, int deviceNo, uint param2, int directions);

        /// <summary>
        /// The counter value of the USB-Counteer is requested.
        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// counter: int
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWGetCounter")]
        public static extern int GetCounter(System.IntPtr obj, int deviceNo, int counter);

        /// <summary>
        /// For internal purposes.
        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        /// param2: unsigned int
        /// mask: int
        /// </summary>
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWSyncDevice")]
        public static extern int SyncDevice(System.IntPtr obj, int deviceNo, uint param2, int mask);

        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWGetMultiConfig")]
        public static extern int GetMultiConfig(System.IntPtr obj, int deviceNo);

        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWIsAmpel")]
        public static extern int IsAmpel(System.IntPtr obj, int deviceNo);

        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWIsSolidState")]
        public static extern int IsSolidState(System.IntPtr obj, int deviceNo);

        /// Return Type: int
        /// obj: CUSBaccess*
        /// deviceNo: int
        [DllImportAttribute("USBaccess.dll", EntryPoint = "FCWIsWatchdogInvert")]
        public static extern int IsWatchdogInvert(System.IntPtr obj, int deviceNo);
    }
}
